package com.miyake.server.user;

import java.util.ArrayList;
import java.util.List;

import javax.jdo.PersistenceManager;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.miyake.client.datamanage.plugin.PluginProperty;
import com.miyake.client.tools.ImageListElement;
import com.miyake.server.DsCommunity;
import com.miyake.server.DsImage;
import com.miyake.server.DsPlugin;
import com.miyake.server.DsUser;
import com.miyake.server.DsUserElement;
import com.miyake.server.PMF;
import com.miyake.server.dsaccess.PluginManager;

public class UserManager {
	private static UserManager userManager = null;
	protected UserManager(){}
	public static UserManager getInstance() {
		if (userManager == null) {
			userManager = new UserManager();
		}
		return userManager;
	}
	
	public void createUser(String email) {
		String key = null;
    	PersistenceManager pm = PMF.get().getPersistenceManager();
    	try {
    		DsUser obj = new DsUser();
    		obj.setEmail(email);
    		
    		obj.getProperties().add(new DsUserElement("Name", ""));
    		obj.getProperties().add(new DsUserElement("Gender", ""));
    		obj.getProperties().add(new DsUserElement("Job", ""));
    		obj.getProperties().add(new DsUserElement("Company", ""));
    		obj.getProperties().add(new DsUserElement("Department", ""));
    		obj.getProperties().add(new DsUserElement("History", ""));
  
    		pm.makePersistent(obj);
    	}
    	catch (Exception e) {
    		e.printStackTrace();
    	}
    	finally {
    		pm.close();    		
    	}
	}
	
	public boolean isValidUser(String email) {
		if (email.equals("miyakemusic@gmail.com")) {
			return true;
		}
		
    	boolean ret = false;
		DsUser user = new GetUser().getByEmail(email);
		
		if (user == null) {
			ret =  false;
		}
		else {
			ret = true;
		}
    	
    	return ret;
	}

	public List<DsUser> getUserList() {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		List<DsUser> ret = null;
		try {
    		String query = "select from " + DsUser.class.getName();
    		ret = (List<DsUser>) pm.newQuery(query).execute();
//    		System.out.println(ret.size());
    	}
    	catch (Exception e) {
    		e.printStackTrace();
    	}
    	finally {
    		pm.close();
    	}
    	return ret;
	}

	public void deleteUser(String key) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
    	try {
    		DsUser obj = pm.getObjectById(DsUser.class, key);
    		pm.deletePersistent(obj);
    	}
    	catch (Exception e) {
    		e.printStackTrace();
    	}
    	finally {
    		pm.close();
    	}
	}

	public DsUser getUser(String key) {
		DsUser ret = new GetUser().getByKey(key);
		System.out.println("getUser()"+ret.getProperties().size());
		for (DsUserElement e : ret.getProperties()) {
			e.getName(); // To avoid bug. Do not remove this code
		}
		return ret;
	}
	
	public DsUser getUserByEmail(String email) {
		DsUser ret = new GetUser().getByEmail(email);
		return ret;
	}
	public void updateUserElement(String key, Integer row, String value) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
    	try {
    		DsUser obj = pm.getObjectById(DsUser.class, key);
			obj.getProperties().get(row).setValue(value);
    	}
    	catch (Exception e) {
    		e.printStackTrace();
    	}
    	finally {
    		pm.close();
    	}
	}

	public List<DsUser> getFriendList(String key) {
		DsUser user = new GetUser().getByKey(key);
		List<DsUser> ret = new ArrayList<DsUser>();
		for (String s : user.getFriends()) {
			ret.add(getUser(s));
		}
		return ret;
	}

	public List<ImageListElement> getAllUsers() {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		List<ImageListElement> ret = new ArrayList<ImageListElement>();
    	try {
			String query = "select from " + DsUser.class.getName();
			@SuppressWarnings("unchecked")
			List<DsUser> list = (List<DsUser>) pm.newQuery(query).execute();
			for (DsUser u : list) {
				ret.add(u.toImageListElement());
			}
    	}
    	catch (Exception e) {
    		e.printStackTrace();
    	}
    	finally {
    		pm.close();
    	}
    	
    	return ret;
	}

	public void addFriend(String myKey, final String friendKey) {
		
		new GetUser() {
			@Override
			protected void update(DsUser dsUser) {
				DsUser u = new GetUser().getByKey(friendKey);
				dsUser.addFriend(u.getEncodedKey());
			}
		}.getByKey(myKey);
	}

	public String getKeyFromEmail(String email) {
		return new GetUser().getByEmail(email).getEncodedKey();
	}

	public void removeFriend(String myKey, final String friendKey) {
		new GetUser() {
			@Override
			protected void update(DsUser dsUser) {
				DsUser u = new GetUser().getByKey(friendKey);
				dsUser.removeFriend(u.getEncodedKey());
			}
		}.getByKey(myKey);
	}

	public List<DsCommunity> getCommunityList(String key, Integer type) {
		DsUser user = new GetUser().getByKey(key);
		List<DsCommunity> ret = new ArrayList<DsCommunity>();
		for (String s : user.getCommunities()) {
			ret.add(getCommunity(s));
		}
		return ret;
	}

	private DsCommunity getCommunity(String key) {
		return new GetCommunity().getByKey(key);
	}
	
	public void addFaceImage(String key, String name, final DsImage image) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			pm.makePersistent(image);
			new GetUser(){
				@Override
				protected void update(DsUser dsUser) {
					dsUser.addImage(image.getEncodedKey());
					image.setNodeKey(dsUser.getEncodedKey());
				}
			}.getByKey(key);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		finally {
			pm.close();
		}
	}
	
	public void removeFaceImage(String key) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			DsImage obj = pm.getObjectById(DsImage.class, key);
			DsUser user = pm.getObjectById(DsUser.class, obj.getEncodedKey());
			for (String s : user.getImages()) {
				if (s.equals(obj.getEncodedKey())) {
					user.getImages().remove(s);
				}
			}
			pm.deletePersistent(obj);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		finally {
			pm.close();
		}
	}
	public void setFaceImage(String key, final Integer number) {
		new GetUser() {
			@Override
			protected void update(DsUser dsUser) {
				dsUser.setImageIndex(number);
			}
		}.getByKey(key);
	}
	public DsUser getMyself() {
	    UserService userService = UserServiceFactory.getUserService();
	    User user = userService.getCurrentUser();
	    if (user == null) {
	    	return null;
	    }
	    return new GetUser().getByEmail(user.getEmail());
	}
	
	public void addAnalysisPlugin(String userKey, final String key) {
		new GetUser() {
			@Override
			protected void update(DsUser dsUser) {
				if (!dsUser.getAnalysisPluginKeys().contains(key)) {
					dsUser.getAnalysisPluginKeys().add(key);
				}
			}
		}.getByKey(userKey);
	}
	
	public void removeAnalysisPlugin(String userKey, final String key) {
		new GetUser() {
			@Override
			protected void update(DsUser dsUser) {
				dsUser.getAnalysisPluginKeys().remove(key);
			}
		}.getByKey(userKey);
	}
	public List<PluginProperty> getAnalysisPluginList(String userKey) {
		List<String> keys = new GetUser().getByKey(userKey).getAnalysisPluginKeys();
		return getPluginList(keys);
	}
	
	protected List<PluginProperty> getPluginList(List<String> keys) {
		List<PluginProperty> ret = new ArrayList<PluginProperty>();
		for (String key : keys) {
			DsPlugin plugin = PluginManager.getInstance().getPlugin(key);
			if (plugin != null) {
				ret.add(plugin.toRemoteObject());
			}
			else {
				keys.remove(key);
			}
		}
		return ret;
	}
	
	public void addFilePlugin(String userKey, final String key) {
		new GetUser() {
			@Override
			protected void update(DsUser dsUser) {
				if (!dsUser.getFilePluginKeys().contains(key)) {
					dsUser.getFilePluginKeys().add(key);
				}
			}
		}.getByKey(userKey);
	}
	
	public List<PluginProperty> getFilePluginList(String userKey) {
		List<String> keys = new GetUser().getByKey(userKey).getFilePluginKeys();
		return getPluginList(keys);
	}
	
	public void removeFilePlugin(String userKey, final String key) {
		new GetUser() {
			@Override
			protected void update(DsUser dsUser) {
				dsUser.getFilePluginKeys().remove(key);
			}
		}.getByKey(userKey);
	}
	public void addChartPlugin(String userKey, final String key) {
		new GetUser() {
			@Override
			protected void update(DsUser dsUser) {
				if (!dsUser.getChartPluginKeys().contains(key)) {
					dsUser.getChartPluginKeys().add(key);
				}
			}
		}.getByKey(userKey);
	}
	
	public void removeChartPlugin(String userKey, final String key) {
		new GetUser() {
			@Override
			protected void update(DsUser dsUser) {
				dsUser.getChartPluginKeys().remove(key);
			}
		}.getByKey(userKey);
	}
	
	public List<PluginProperty> getChartPluginList(String userKey) {
		List<String> keys = new GetUser().getByKey(userKey).getChartPluginKeys();
		return getPluginList(keys);
	}
}
